package com.hardy.job;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Author: fuxh3@lenovo.com
 * Date: Created in 2018/3/14 0014
 */
public class WritePersonInfo {
    private final static String infilePath = "D:/name_list_in.txt";
    private final static String outfilePath = "D:/name_list_out.txt";
    private final static String sortFilePath = "D:/name_list_result.txt";

    public static void main(String[] args) {
        try {
            /*从原始数据中过滤出1995年1月1日到1999年12月31日出生的人写入到name_list_out.txt文件中*/
            readData();
            /*分割name_list_out.txt文件为一个个小文件*/
            separateBigFile();
            /*将单个小文件排序*/
            everySingleFileSort();
            /*合并已经排序的小文件的结果到name_list_result.txt*/
            mergeSmallFile();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void everySingleFileSort() throws Exception {
        LinkedList<Card> data;
        for (int i = 0; i < 5; i++) {
            data = new LinkedList<Card>();
            String path = "D:" + File.separator + "data" + i + ".txt";
            FileReader fr = new FileReader(path);
            BufferedReader br = new BufferedReader(fr);
            while (br.ready()) {
                String lineTxt = br.readLine();
                String regEx = "(\\d{17}[\\d|x|X])";
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(lineTxt);
                if (m.find()) {
                    String feteDay = getFeteDay(m.group(0));
                    Integer birthday = Integer.parseInt(feteDay);
                    data.add(new Card(birthday, lineTxt));
                }
            }
            Collections.sort(data, new Comparator<Card>() {
                @Override public int compare(Card o1, Card o2) {
                    return o1.getBrithDay() - o2.getBrithDay();
                }
            });
            datasWrite(data, path);
            br.close();
            fr.close();
        }

    }

    private static void datasWrite(LinkedList<Card> data, String path) throws IOException {
        FileWriter fw = new FileWriter(path);
        BufferedWriter bw = new BufferedWriter(fw);
        for (Iterator<Card> iterator = data.iterator(); iterator.hasNext(); ) {
            Card card = iterator.next();
            bw.write(card.getDetailInfo() + "\r\n");
        }
        bw.close();
        fw.close();
    }

    public static void mergeSmallFile() throws Exception {
        PriorityQueue<Card> queue = new PriorityQueue<Card>(5, new Comparator<Card>() {
            @Override public int compare(Card o1, Card o2) {
                return o1.brithDay - o2.brithDay;
            }
        });
        FileReader fr = null;
        BufferedReader br = null;
        FileWriter fw = new FileWriter(sortFilePath);
        BufferedWriter bw = new BufferedWriter(fw);
        List<FileReader> frList = new LinkedList<FileReader>();
        List<BufferedReader> brList = new LinkedList<BufferedReader>();
        int n;
        for (int i = 0; i < 5; i++) {
            String path = "D:" + File.separator + "data" + i + ".txt";
            fr = new FileReader(path);
            br = new BufferedReader(fr);
            frList.add(fr);
            brList.add(br);
        }
        //把每个小文件的第一行记录读入队列中
        for (int i = 0; i <= 5; i++) {
            BufferedReader buffR;
            if (i == 5) {
                while (queue.size() != 0) {
                    Card card = queue.poll();
                    bw.write(card.detailInfo + "\r\n");
                    buffR = brList.get(card.getN());
                    while (buffR.ready() && queue.size() < 5) {
                        String lineTxt = buffR.readLine();
                        String regEx = "(\\d{17}[\\d|x|X])";
                        Pattern p = Pattern.compile(regEx);
                        Matcher m = p.matcher(lineTxt);
                        if (m.find()) {
                            String feteDay = getFeteDay(m.group(0));
                            Integer birthday = Integer.parseInt(feteDay);
                            Card card1 = new Card(birthday, lineTxt, card.getN());
                            queue.add(card1);
                        }
                    }
                }
                break;
            }
            buffR = brList.get(i);
            while (buffR.ready() && queue.size() < 5) {
                String lineTxt = buffR.readLine();
                String regEx = "(\\d{17}[\\d|x|X])";
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(lineTxt);
                if (m.find()) {
                    String feteDay = getFeteDay(m.group(0));
                    Integer birthday = Integer.parseInt(feteDay);
                    Card card = new Card(birthday, lineTxt, i);
                    queue.add(card);
                    break;
                }
            }
        }
        bw.close();
        fw.close();
        // 遍历关闭所有的子文件流
        for (Iterator iterator = brList.iterator(); iterator.hasNext(); ) {
            BufferedReader it = (BufferedReader) iterator.next();
            it.close();
        }
        for (Iterator iterator = frList.iterator(); iterator.hasNext(); ) {
            FileReader it = (FileReader) iterator.next();
            it.close();
        }
    }

    private static void readData() {
        try {
            String encoding = "utf-8";
            File file = new File(infilePath);
            if (file.isFile() && file.exists()) { //判断文件是否存在
                InputStreamReader read = new InputStreamReader(new FileInputStream(file),
                                                encoding);//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                FileWriter fw = new FileWriter(outfilePath);
                BufferedWriter bw = new BufferedWriter(fw);
                String lineTxt = null;
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    String regEx = "(\\d{17}[\\d|x|X])";
                    Pattern p = Pattern.compile(regEx);
                    Matcher m = p.matcher(lineTxt);
                    if (m.find()) {
                        String feteDay = getFeteDay(m.group(0));
                        Integer birthday = Integer.parseInt(feteDay);
                        if (birthday > 19950101 && birthday < 19991231) {
                            bw.write(lineTxt + "\r\n");
                        }
                    }
                }
                read.close();
            } else {
                System.out.println("找不到指定的文件");
            }
        } catch (Exception e) {
            System.out.println("读取文件内容出错");
            e.printStackTrace();
        }
    }

    private static String getFeteDay(String idCardNumber) {

        return idCardNumber.substring(6, 10) + "" + idCardNumber.substring(10, 12) + ""
                                        + idCardNumber.substring(12, 14);
    }

    public static void separateBigFile() throws IOException {
        FileReader fr = new FileReader(outfilePath);
        BufferedReader br = new BufferedReader(fr);
        FileWriter fw = null;
        BufferedWriter bw = null;
        File file = null;
        List<FileWriter> fwList = new LinkedList<FileWriter>();
        List<BufferedWriter> bwList = new LinkedList<BufferedWriter>();
        for (int i = 0; i < 5; i++) {
            file = new File("D:" + File.separator + "data" + i + ".txt");
            fw = new FileWriter(file);
            bw = new BufferedWriter(fw);
            fwList.add(fw);
            bwList.add(bw);
        }
        while (br.ready()) {
            for (Iterator<BufferedWriter> iterator = bwList.iterator(); iterator.hasNext(); ) {
                BufferedWriter it = iterator.next();
                it.write(br.readLine() + "\r\n");
                continue;// 第一个bw读完让下一个读，然后写入小文件
            }
        }
        br.close();
        fr.close();
        // 遍历关闭所有子文件流
        for (Iterator iterator = bwList.iterator(); iterator.hasNext(); ) {
            BufferedWriter it = (BufferedWriter) iterator.next();
            it.close();
        }
        for (Iterator iterator = fwList.iterator(); iterator.hasNext(); ) {
            FileWriter it = (FileWriter) iterator.next();
            it.close();
        }

    }

    static class Card {
        Integer brithDay;
        String detailInfo;
        Integer n;

        public Integer getN() {
            return n;
        }

        public void setN(Integer n) {
            this.n = n;
        }


        public Card(Integer brithDay, String detailInfo) {
            this.brithDay = brithDay;
            this.detailInfo = detailInfo;
        }

        public Card(Integer brithDay, String detailInfo, Integer n) {
            this.brithDay = brithDay;
            this.detailInfo = detailInfo;
            this.n = n;
        }

        public Card() {

        }

        public Integer getBrithDay() {
            return brithDay;
        }

        public void setBrithDay(Integer brithDay) {
            this.brithDay = brithDay;
        }

        public String getDetailInfo() {
            return detailInfo;
        }

        public void setDetailInfo(String detailInfo) {
            this.detailInfo = detailInfo;
        }
    }
}
